;/*=============================================================================
;#    The element-comm is a tentative program used to test our ideas.           
;#                       Copyright (C)  bgao                                    
;#
;#     This program is free software; you can redistribute it and/or            
;#      modify it under the terms of the GNU General Public License             
;#     as published by the Free Software Foundation; either version 2           
;#         of the License, or (at your option) any later version.               
;#
;#     This program is distributed in the hope that it will be useful,          
;#    but WITHOUT ANY WARRANTY; without even the implied warranty of           
;#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            
;#             GNU General Public License for more details.                    
;#
;#    You should have received a copy of the GNU General Public License        
;#     along with this program; if not, write to the Free Software             
;#      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,             
;#                       MA  02110-1301, USA.                                  
;#==============================================================================
;# $Id$ 
;#
;# $Author$ 
;#
;# $Revision$ 
;#
;# $Date$ 
;#
;# Description: 
;#
;=============================================================================*/
	GET 2410addr.inc
	GET option.inc
	
	IMPORT wsn_thread0_context
	IMPORT wsn_sched_mode	
	IMPORT wsn_int_nesting
	IMPORT wsn_disable_sched
	
	IMPORT wsn_int_sched
	IMPORT C_IRQHandler

	EXPORT IsrIRQ

 if :def: __ARMCC_REALVIEW2_2
	PRESERVE8
	REQUIRE8	{TRUE}
 endif
	area IRQTEXT, code, readonly
	
;*********************************************************************

IsrIRQ  
	;protectd with irq disable
	;save lr-4 as return pc
	SUB 	lr, lr, #4
	STMFD 	sp!, {lr}
	;save SPSR_irq and ip
	MRS 	r14, SPSR
	STMFD 	sp!, {r12,r14}

	;TODO:clear IRQ pending and enable IRQ interrupt
	;swtich to SVC mode and FIQ enable
	MSR		cpsr_c, #0x93
	
	;save SVC context
	STMFD 	sp!,{r0-r3,lr}

	;push disable_sched 
	LDR		R0, =wsn_disable_sched
	LDRB	R1, [R0]
	STMFD	sp!, {R1}
	
	;wsn_int_nesting ++
	LDR		R0, =wsn_int_nesting
	LDRB	R1, [R0]
	ADD		R1, R1, #1
	STRB	R1, [R0]
	CMP		R1, #2
	BHS		WSN_ISR_START

	;check the system mode in thread sched or task sched
	LDR		R0, =wsn_sched_mode
	LDRB	R1, [R0]
	CMP		R1, #2
	BNE		WSN_ISR_START
	
	;if thread was interrupt change SP to system stack
	MOV		R0, SP	
	LDR		R1, =wsn_thread0_context
	LDR		SP, [R1]
	STMFD   SP!, {R0}
	
WSN_ISR_START	
	BL 		C_IRQHandler
	
	;interrupt disable
;	MRS 	r0, CPSR
;	ORR 	r0, r0, #0xC0
;	MSR 	CPSR_c, r0
	
	;wsn_int_nesting --
	LDR		R0, =wsn_int_nesting
	LDRB	R1, [R0]
	SUB		R1, R1, #1
	STRB	R1, [R0]

	;check if it is the last interrupt
	CMP 	R1, #0
	BNE		WSN_ISR_RET

	;check the system mode in thread sched or task sched
	LDR  	R0, =wsn_sched_mode
	LDRB	R1, [R0]
	CMP  	R1, #2
	BNE	  	WSN_ISR_END

	;if thread was interrupt change SP back to thread stack
	LDMFD	SP!, {R0}
	LDR		R1, =wsn_thread0_context
	STR		SP, [R1]
	MOV		SP, R0
	
WSN_ISR_END	
	BL		wsn_int_sched
	

WSN_ISR_RET

	;restore disable_sched 
	LDR		R0, =wsn_disable_sched
	LDMFD	sp!, {R1}
	STRB		R1, [R0]
	
	;restore SVC registers
	LDMFD 	sp!, {r0-r3,lr}
	;back to IRQ mode	 and disable IRQ interrupt
	MSR		cpsr_c, #0x92
	
	;restore SPSR
	LDMFD 	sp!, {r12,r14}
	MSR 	SPSR_cf, r14
	;return from irq
	LDMFD 	sp!, {pc}^

	end
                

	
